package org.jeecg.modules.system.controller;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qixin.modules.eaBasic.util.ChangeIdToNameUtil;
import com.qixin.modules.eaBasic.util.MapUtil;
import com.qixin.modules.rzInvoice.entity.EaBill;
import com.qixin.modules.rzInvoice.entity.EaBillItem;
import com.qixin.modules.rzInvoice.mapper.EaBillItemMapper;
import com.qixin.modules.version.service.IFybxVersionManageService;
import com.qixin.utils.FastDFSClient;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.fapiao.glority.GlorityService;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.CommonUtils;
import org.jeecg.common.util.DateFormatUtil;
import org.jeecg.common.util.EmptyUtil;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.nc.vo.SysUserPsnVo;
import org.jeecg.modules.system.entity.CurrentDateTime;
import org.jeecg.modules.system.entity.SysDictItem;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.mapper.SysDictItemMapper;
import org.jeecg.modules.system.mapper.SysDictMapper;
import org.jeecg.modules.system.model.SysDepartTreeModel;
import org.jeecg.modules.system.model.TreeSelectModel;
import org.jeecg.modules.system.service.ISysDepartService;
import org.jeecg.modules.system.service.ISysDictService;
import org.jeecg.modules.system.service.ISysUserService;
import org.jeecg.modules.system.vo.AllowanceCostVo;
import org.jeecg.modules.system.vo.SysDepartVo;
import org.jeecg.modules.system.vo.SysUserPageVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <p>
 * 用户表 前端控制器
 * </p>
 *
 * @Author scott
 * @since 2018-12-20
 */
@Api(tags="app系统管理")
@Slf4j
@RestController
@RequestMapping("/app/api/sys")
public class ApiSystemController {
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private ISysDepartService sysDepartService;
    @Autowired
    private ISysDictService sysDictService;
    @Autowired
    private SysDictMapper sysDictMapper;
    @Value(value = "${jeecg.path.upload}")
    private String uploadpath;
    /**
     * 本地：local minio：minio 阿里：alioss
     */
    @Value(value = "${jeecg.uploadType}")
    private String uploadType;

    @Value("${server.fileurl}")
    private String contextPath;

    @Value("${qixin.app.donwloadUrl}")
    private String donwloadUrl;

    @Autowired
    private ChangeIdToNameUtil changeIdToNameUtil;

    @Autowired
    private EaBillItemMapper eaBillItemMapper;

    @Autowired
    private FastDFSClient fastDFSClient;

    @Autowired
    private SysDictItemMapper sysDictItemMapper;

    @Autowired
    private IFybxVersionManageService fybxVersionManageService;


    /**
     * @Description: 用户列表
     * @author: wly
     * @date: 2021/7/22 11:22
     */
    @AutoLog(value = "app用户列表查询")
    @ApiOperation(value="app用户列表查询", notes="app用户列表查询")
    @RequestMapping(value = "/user/queryList", method = RequestMethod.GET)
    public Result<?> queryList() {
        Result<List<SysUser>> result = new Result<>();
        List<SysUser> userList = sysUserService.queryAgencyUserList();
        result.setSuccess(true);
        result.setResult(userList);
        return result;

//        if(EmptyUtil.checkNull(sysUserPageVo.getUserType()).equals("")){
//            sysUserPageVo.setUserType("1");    //系统用户
//        }
//
//        Map<String,Object> params = new HashMap<String,Object>();
//        params.put("pageNo",sysUserPageVo.getPageNo());
//        params.put("pageSize",sysUserPageVo.getPageSize());
//        params.put("userType",sysUserPageVo.getUserType());
//        params.put("orgCode",sysUserPageVo.getOrgCode());
//
//        Page<SysUser> pageList = new Page<SysUser>(sysUserPageVo.getPageNo(), sysUserPageVo.getPageSize());
//        pageList = sysUserService.queryAppList(pageList,params);
//        result.setSuccess(true);
//        result.setResult(pageList);
//        return result;
    }

    /**
     * 查询数据 查出所有部门,并以树结构数据格式响应给前端
     *
     * @return
     */
    @AutoLog(value = "app部门列表查询")
    @ApiOperation(value="app部门列表查询", notes="app部门列表查询")
    @RequestMapping(value = "/sysDepart/queryTreeList", method = RequestMethod.POST)
    public Result<List<SysDepartTreeModel>> queryTreeList() {
        Result<List<SysDepartTreeModel>> result = new Result<>();
        try {
            List<SysDepartTreeModel> list = sysDepartService.queryTreeList();
            result.setResult(list);
            result.setSuccess(true);
        } catch (Exception e) {
            log.error(e.getMessage(),e);
        }
        return result;
    }

    /**
     * 查询数据 查询支付方式给前端
     *
     * @return
     */
    @AutoLog(value = "app支付方式查询")
    @ApiOperation(value="app支付方式查询", notes="app支付方式查询")
    @RequestMapping(value = "/sysDict/queryPaymentMethod", method = RequestMethod.POST)
    public Result<List<DictModel>> queryPaymentMethod() {
        Result<List<DictModel>> result = new Result<>();
        try {
            List<DictModel> list = sysDictService.queryDictItemsByCode("payment_method");  //code
            result.setResult(list);
            result.setSuccess(true);
        } catch (Exception e) {
            log.error(e.getMessage(),e);
        }
        return result;
    }

    /**
     * 查询数据 查询当前日期/时间给前端
     *
     * @return
     */
    @AutoLog(value = "app获取服务端配置信息")
    @ApiOperation(value="app获取服务端配置信息", notes="app获取服务端配置信息")
    @RequestMapping(value = "/getServerConfig", method = RequestMethod.POST)
    public Result<CurrentDateTime> getServerConfig() {
        CurrentDateTime currentDateTime = new CurrentDateTime();

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = new Date();
        String dateStr = simpleDateFormat.format(date);
        currentDateTime.setCurrentDateTime(dateStr);

        return Result.OK(currentDateTime);
    }

    /**
     * 查询数据 查询发票类型给前端
     *
     * @return
     */
    @AutoLog(value = "app发票类型查询")
    @ApiOperation(value="app发票类型查询", notes="app发票类型查询")
    @RequestMapping(value = "/sysDict/queryBillType", method = RequestMethod.POST)
    public Result<List<DictModel>> queryBillType() {
        Result<List<DictModel>> result = new Result<>();
        try {
            List<DictModel> list = sysDictService.queryDictItemsByCode("ea_invoice_type");  //code
            result.setResult(list);
            result.setSuccess(true);
        } catch (Exception e) {
            log.error(e.getMessage(),e);
        }
        return result;
    }

    /**
     * 查询数据 查询发票消费类型给前端
     *
     * @return
     */
    @AutoLog(value = "app发票消费类型查询")
    @ApiOperation(value="app发票消费类型查询", notes="app发票消费类型查询")
    @RequestMapping(value = "/sysDict/queryCostType", method = RequestMethod.POST)
    public Result<List<DictModel>> queryCostType() {
        Result<List<DictModel>> result = new Result<>();
        try {
            List<DictModel> list = sysDictService.queryDictItemsByCode("cost_type");  //code
            result.setResult(list);
            result.setSuccess(true);
        } catch (Exception e) {
            log.error(e.getMessage(),e);
        }
        return result;
    }

    /**
     * 查询数据 查询火车的座位类型
     *
     * @return
     */
    @AutoLog(value = "app查询火车的座位类型")
    @ApiOperation(value="app查询火车的座位类型", notes="app查询火车的座位类型")
    @RequestMapping(value = "/sysDict/queryTrainSeatType", method = RequestMethod.POST)
    public Result<List<Map<String,Object>>> queryTrainSeatType() {
        Result<List<Map<String,Object>>> result = new Result<>();
        try {
            List<Map<String,Object>> list = sysDictMapper.queryTrainSeatType();
            result.setResult(list);
            result.setSuccess(true);
        } catch (Exception e) {
            log.error(e.getMessage(),e);
        }
        return result;
    }


    /**
     * 查询数据 查询飞机舱位类型
     *
     * @return
     */
    @AutoLog(value = "app查询飞机舱位类型")
    @ApiOperation(value="app查询飞机舱位类型", notes="app查询飞机舱位类型")
    @RequestMapping(value = "/sysDict/queryAirPlaneSeatType", method = RequestMethod.POST)
    public Result<List<Map<String,Object>>> queryAirPlaneSeatType() {
        Result<List<Map<String,Object>>> result = new Result<>();
        try {
            List<Map<String,Object>> list = sysDictMapper.queryAirPlaneSeatType();
            result.setResult(list);
            result.setSuccess(true);
        } catch (Exception e) {
            log.error(e.getMessage(),e);
        }
        return result;
    }

    /**
     * 通过international_flag(国内[D]国际航班标签),class_name(舱位登记)获取航空舱位数据字典id
     *
     * @param map
     * @return
     */
    @AutoLog(value = "获取航空舱位数据字典id")
    @ApiOperation(value="获取航空舱位数据字典id", notes="获取航空舱位数据字典id")
    @PostMapping(value = "/queryAirPlaneDictByClassName")
    public Result<?> queryAirPlaneDictByClassName(@RequestBody Map<String,Object> map) {
        Map<String, Object> resutlList = sysDictService.queryAirPlaneDictByClassName(map);
        return Result.OK(resutlList);
    }

    /**
     * app查询组织/公司列表
     *
     * @return
     */
    @AutoLog(value = "app查询组织/公司(org_category=1)列表")
    @ApiOperation(value="app查询组织/公司(org_category=1)列表", notes="app查询组织/公司(org_category=1)列表")
    @RequestMapping(value = "/sysDepart/queryCompanyList", method = RequestMethod.POST)
    public Result<List<SysDepartTreeModel>> queryCompanyList() {
        Result<List<SysDepartTreeModel>> result = new Result<>();
        try {
            List<SysDepartTreeModel> list = sysDepartService.queryCompanyList();
            result.setResult(list);
            result.setSuccess(true);
        } catch (Exception e) {
            log.error(e.getMessage(),e);
        }
        return result;
    }

    /**
     * app查询部门列表
     *
     * @return
     */
    @AutoLog(value = "app查询部门(org_category=2)列表")
    @ApiOperation(value="app查询部门(org_category=2)列表", notes="app查询部门(org_category=2)列表")
    @RequestMapping(value = "/sysDepart/queryDepartList", method = RequestMethod.POST)
    public Result<List<SysDepartTreeModel>> queryDepartList(@RequestBody SysDepartVo sysDepartVo) {
        Result<List<SysDepartTreeModel>> result = new Result<>();
        String id = EmptyUtil.checkNull(sysDepartVo.getId());
        try {
            List<SysDepartTreeModel> list = sysDepartService.queryDepartList(id);
            result.setResult(list);
            result.setSuccess(true);
        } catch (Exception e) {
            log.error(e.getMessage(),e);
        }
        return result;
    }

    /**
     * @Description: 查询代理用户列表(包括自己)
     * @author: wly
     * @date: 2021/9/23 11:22
     * update wjb 2022/1/5 10:58
     */
    @ApiOperation(value="根据代理人查询对应委托人列表（包含自己）", notes="根据代理人查询对应委托人列表（包含自己）")
    @RequestMapping(value = "/user/queryAgencyUserList", method = RequestMethod.GET)
    public Result<?> queryAgencyUserList() {
        Result<List<SysUserPsnVo>> result = new Result<>();
        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        List<SysUserPsnVo> userList = sysUserService.queryUserList(loginUser);
        result.setSuccess(true);
        result.setResult(userList);
        return result;
    }

    /**
     * app查询费用项目树形
     *
     * @return
     */
    @AutoLog(value = "app查询费用项目树形")
    @ApiOperation(value="app查询费用项目树形", notes="app查询费用项目树形")
    @RequestMapping(value = "/freeType/loadFeeTypeTreeList", method = RequestMethod.POST)
    public Result<List<TreeSelectModel>> loadFeeTypeTreeList() {
        Result<List<TreeSelectModel>> result = new Result<>();
        try {
            List<TreeSelectModel> list = sysDictService.loadFeeTypeTreeList();
            result.setResult(list);
            result.setSuccess(true);
        } catch (Exception e) {
            log.error(e.getMessage(),e);
        }
        return result;
    }

    /**
     * app查询接待类型
     *
     * @return
     */
    @AutoLog(value = "app查询接待类型")
    @ApiOperation(value="app查询接待类型", notes="app查询接待类型")
    @RequestMapping(value = "/sysDict/getReceptionType", method = RequestMethod.POST)
    public Result<List<DictModel>> getReceptionType() {
        Result<List<DictModel>> result = new Result<>();
        try {
            List<DictModel> list = sysDictService.queryDictItemsByCode("reception_type");  //code
            result.setResult(list);
            result.setSuccess(true);
        } catch (Exception e) {
            log.error(e.getMessage(),e);
        }
        return result;
    }

    /**
     * app查询目的地
     *
     * @return
     */
    @AutoLog(value = "app查询目的地")
    @ApiOperation(value="app查询目的地", notes="app查询目的地")
    @RequestMapping(value = "/regioin/getRegionList", method = RequestMethod.POST)
    public Result<List<TreeSelectModel>> getRegionList() {
        Result<List<TreeSelectModel>> result = new Result<>();
        try {
            List<TreeSelectModel> list = sysDictService.loadRegionTreeList();
            result.setResult(list);
            result.setSuccess(true);
        } catch (Exception e) {
            log.error(e.getMessage(),e);
        }
        return result;
    }

    /**
     * app查询交通工具
     *
     * @return
     */
    @AutoLog(value = "app查询交通工具")
    @ApiOperation(value="app查询交通工具", notes="app查询交通工具")
    @RequestMapping(value = "/sysDict/getVehicleList", method = RequestMethod.POST)
    public Result<List<DictModel>> getVehicleList() {
        Result<List<DictModel>> result = new Result<>();
        try {
            List<DictModel> list = sysDictService.queryDictItemsByCode("ea_vehicle_dict");  //code
            result.setResult(list);
            result.setSuccess(true);
        } catch (Exception e) {
            log.error(e.getMessage(),e);
        }
        return result;
    }


    /**
     * app查询出差类型
     *
     * @return
     */
    @AutoLog(value = "app查询出差类型")
    @ApiOperation(value="app查询出差类型", notes="app查询出差类型")
    @RequestMapping(value = "/sysDict/getBusinessType", method = RequestMethod.POST)
    public Result<List<DictModel>> getBusinessType() {
        Result<List<DictModel>> result = new Result<>();
        try {
            List<DictModel> list = sysDictService.queryDictItemsByCode("ea_business_type");  //code
            result.setResult(list);
            result.setSuccess(true);
        } catch (Exception e) {
            log.error(e.getMessage(),e);
        }
        return result;
    }

    /**
     * @Description: app司机列表
     * @author: wly
     * @date: 2021/7/22 11:22
     * @param sysUserPageVo
     */
    @AutoLog(value = "app司机列表")
    @ApiOperation(value="app司机列表", notes="app司机列表")
    @RequestMapping(value = "/user/queryDriverList", method = RequestMethod.POST)
    public Result<?> queryDriverList(@RequestBody SysUserPageVo sysUserPageVo) {
        Result<Page<SysUser>> result = new Result<>();
        if(EmptyUtil.checkNull(sysUserPageVo.getUserType()).equals("")){
            sysUserPageVo.setUserType("5");    //系统用户
        }

        Map<String,Object> params = new HashMap<String,Object>();
        params.put("pageNo",sysUserPageVo.getPageNo());
        params.put("pageSize",sysUserPageVo.getPageSize());
        params.put("userType",sysUserPageVo.getUserType());
        params.put("orgCode",sysUserPageVo.getOrgCode());

        Page<SysUser> pageList = new Page<SysUser>(sysUserPageVo.getPageNo(), sysUserPageVo.getPageSize());
        pageList = sysUserService.queryAppList(pageList,params);
        result.setSuccess(true);
        result.setResult(pageList);
        return result;
    }

    /**
     * 发票识别-单张(Api)
     *
     * @return
     */
    @AutoLog(value = "发票识别-单张(Api)")
    @ApiOperation(value = "发票识别-单张(Api)", notes = "发票识别-单张(Api)")
    @PostMapping(value = "/identify")
    @Transactional
    public Result<?> identifyApi(HttpServletRequest request) {
        Result<?> result = new Result<>();
        String savePath = "";
        String bizPath = request.getParameter("biz");
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        MultipartFile file = multipartRequest.getFile("file");// 获取上传文件对象
        if (null == file) {
            result.setMessage("文件不能为空！");
            result.setSuccess(false);
            return result;
        }

        if (CommonConstant.UPLOAD_TYPE_LOCAL.equals(uploadType)) {
            //本地存储
//            savePath = this.uploadLocal(file,"");
            try {
                savePath = fastDFSClient.uploadFile(file);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (oConvertUtils.isNotEmpty(savePath)) {
            result.setMessage(savePath);
            result.setSuccess(true);
        } else {
            result.setMessage("上传失败！");
            result.setSuccess(false);
            return result;
        }

        // 调用发票识别接口- 校验发票
        try {
            // 取本地存储路径
            //String ctxPath = uploadpath + File.separator + savePath;
            String ctxPath = savePath;
            //File ocrFile = new File(ctxPath);
            File ocrFile = fastDFSClient.transferToFile(file);
            // 发票识别
            String res = GlorityService.getItemInfo(ocrFile);

            JSONObject jsonObject = JSON.parseObject(res);
            if (jsonObject.getIntValue("result") == 0) {
                result.setMessage("发票识别出现异常,错误信息：" + res);
                result.setSuccess(false);
                return result;
            }


            // 保存发票识别数据 --begin
            //this.saveData(jsonObject,savePath);
            Map<String,Object> returnMap = new HashMap<String,Object>();
            JSONObject rsdata = jsonObject.parseObject(jsonObject.getString("response")).getJSONObject("data");
            JSONArray identifyResults = rsdata.getJSONArray("identify_results");

            Map<String,Object> billMap = new HashMap<String,Object>();
            for (int idx = 0; idx < identifyResults.size(); idx++) {
                JSONObject rs = identifyResults.getJSONObject(idx);
                JSONObject data = rs.getJSONObject("details");
                JSONArray items = data.getJSONArray("items");
                if(items == null || items.size() == 0){
                    items = data.getJSONArray("flights");     //飞机明细
                }
                String type = rs.getString("type");

                //将识别的信息详情,转换成发票信息实体,返回前端
                EaBill eabill = new EaBill();
                eabill.setSource("2");   //发票录入方式 ：1手动录入，2发票识别
                String kindId = changeIdToNameUtil.getIdByKindName(data.getString("kind"));
                eabill.setKind(kindId);   //发票消费类型
                if(kindId.equals("7")){
                    eabill.setKindName("其它");
                }else{
                    eabill.setKindName(data.getString("kind"));
                }
                eabill.setCode(data.getString("code"));       //发票代码
                eabill.setNumber(data.getString("number"));   //发票号码

                //格式化日期
                String date = data.getString("date");    //开票日期
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年M月d日");
                if(date != null){
                    Date dateDate = null;
                    try {
                        Date ydmDate = simpleDateFormat.parse(date);
                        SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyy-MM-dd");
                        String dateDateStr = simpleDateFormat2.format(ydmDate);
                        dateDate = simpleDateFormat2.parse(dateDateStr);
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                    eabill.setDate(dateDate);
                }
                String pretax_amount1 = data.getString("pretax_amount");
                String total1 = data.getString("total");
                String tax1 = data.getString("tax");

                try {
                    BigDecimal pretax_amount2 = new BigDecimal(pretax_amount1);
                    eabill.setPretaxAmount(pretax_amount1);    //税前金额
                }catch (Exception e){
                    eabill.setPretaxAmount("0");    //税前金额
                }
                try {
                    BigDecimal total2 = new BigDecimal(total1);
                    eabill.setTotal(total1);    //价税合计（小写）
                }catch (Exception e){
                    eabill.setTotal("0");    //价税合计（小写）
                }
                try {
                    BigDecimal tax2 = new BigDecimal(tax1);
                    eabill.setTax(tax1);    //税额
                }catch (Exception e){
                    eabill.setTax("0");    //税额
                }

                eabill.setProvince(changeIdToNameUtil.getIdByRegionName(data.getString("province")));    //省
                eabill.setCity(changeIdToNameUtil.getIdByRegionName(data.getString("city")));    //市
                eabill.setProvinceName(data.getString("province"));    //省
                eabill.setCityName(data.getString("city"));    //市
                eabill.setRemark(data.getString("remark"));    //备注
                eabill.setTimeGeton(data.getString("time_geton"));    //上车时间(出租车)
                eabill.setTimeGetoff(data.getString("time_getoff"));    //下车时间(出租车)
                eabill.setMileage(data.getString("mileage"));    //里程(出租车)

                eabill.setTime(data.getString("time"));    //乘车时间(火车票)
                eabill.setStationGeton(data.getString("station_geton"));    //上车车站(火车票)
                eabill.setStationGetoff(data.getString("station_getoff"));    //下车车站(火车票)
                String train_number = data.getString("train_number");   //车次(火车票)
                eabill.setTrainNumber(train_number);
                String seat = data.getString("seat");   //车次(火车票)

                eabill.setSeat(changeIdToNameUtil.getIdByTrainName(seat,train_number));
                List<Map<String,Object>> mapList = eaBillItemMapper.getAirPlaneSeatName(changeIdToNameUtil.getIdByTrainName(seat,train_number));
                if(mapList.size() > 0){
                    Map<String,Object> map2 = mapList.get(0);
                    eabill.setSeatName(EmptyUtil.checkNull(map2.get("classNameName")));
                }
                eabill.setEntranceHighway(data.getString("entrance"));    //入口(过路费)
                eabill.setExitHighway(data.getString("exit"));    //出口(过路费)
                try {
                    BigDecimal fare = !"".equals(EmptyUtil.checkNull(data.getString("fare"))) ? new BigDecimal(data.getString("fare")) : new BigDecimal(0);
                    eabill.setFare(fare);    //票价(航空运输电子客票行程单)
                }catch (Exception e){
                    eabill.setFare(new BigDecimal(0));    //票价(航空运输电子客票行程单)
                }
                try {
                    BigDecimal fuelSurcharge = !"".equals(EmptyUtil.checkNull(data.getString("fuel_surcharge"))) ? new BigDecimal(data.getString("fuel_surcharge")) : new BigDecimal(0);
                    eabill.setFuelSurcharge(fuelSurcharge);    //燃油附加费(航空运输电子客票行程单)
                }catch (Exception e){
                    eabill.setFuelSurcharge(new BigDecimal(0));    //燃油附加费(航空运输电子客票行程单)
                }
                try {
                    BigDecimal caacDevelopmentFund = !"".equals(EmptyUtil.checkNull(data.getString("caac_development_fund"))) ? new BigDecimal(data.getString("caac_development_fund")) : new BigDecimal(0);
                    eabill.setCaacDevelopmentFund(caacDevelopmentFund);    //民航发展基金(航空运输电子客票行程单)
                }catch (Exception e){
                    eabill.setCaacDevelopmentFund(new BigDecimal(0));    //民航发展基金(航空运输电子客票行程单)
                }
                try {
                    BigDecimal insurance = !"".equals(EmptyUtil.checkNull(data.getString("insurance"))) ? new BigDecimal(data.getString("insurance")) : new BigDecimal(0);
                    eabill.setInsurance(insurance);    //保险费(航空运输电子客票行程单)
                }catch (Exception e){
                    eabill.setInsurance(new BigDecimal(0));    //保险费(航空运输电子客票行程单)
                }
                String international_flag = EmptyUtil.checkNull(data.getString("international_flag"));
                if(type.equals("10506")){    //航空发票
                    if(international_flag.contains("国内")){
                        eabill.setInternationalFlag("D");            //国内国际标签(国内D)
                    }else if(international_flag.contains("国际")){
                        eabill.setInternationalFlag("F");            //国内国际标签(国内D)
                    }else{
                        eabill.setInternationalFlag("");             //国内国际标签(国内D)
                    }
                }

                String blockChain = EmptyUtil.checkNull(data.getString("block_chain"));           //区块链标记
                String transitMark = EmptyUtil.checkNull(data.getString("transit_mark"));         //通行费标志
                String electronicMark = EmptyUtil.checkNull(data.getString("electronic_mark"));   //是否为电子增票
                if(type.equals("10102") && blockChain.equals("1")){
                    type = "1010201";
                }
                if(type.equals("10102") && transitMark.equals("1")){
                    type = "1010202";
                }
                if(type.equals("10100") && electronicMark.equals("1")){
                    type = "1010001";
                }

                String effectiveTypeName = changeIdToNameUtil.getEffectiveNameByTypeId(type);
                String typeName = changeIdToNameUtil.getNameByTypeId(type);
                if(effectiveTypeName.equals("")){
                    throw new RuntimeException("发票类型:" + typeName + "未启用,请录入其它类型发票");
                }else{
                    eabill.setType(type);  //发票类型
                    eabill.setTypeName(effectiveTypeName);  //发票类型名称
                }
                eabill.setBillFile(ctxPath.replaceAll(uploadpath,contextPath).replaceAll("\\\\",""));
//                eabill.setBillFile(savePath);

                billMap = JSONObject.parseObject(JSONObject.toJSONString(eabill, SerializerFeature.WriteMapNullValue),Map.class);
                MapUtil.nullToEmpty(billMap);  //将map中的null值转换成空字符

                //开票日期
                if(!EmptyUtil.checkNull(billMap.get("date")).equals("")){
                    Long date2 = Long.parseLong(billMap.get("date").toString());
                    String date2Str = DateFormatUtil.formatDateyyMMdd(date2);
                    billMap.put("date",date2Str);
                }

                //添加发票图片fileList
                List<Map<String,Object>> fileList = new ArrayList<Map<String,Object>>();
                Map<String,Object> fileMap = new HashMap<String,Object>();
                fileMap.put("url",ctxPath.replaceAll(uploadpath,contextPath).replaceAll("\\\\",""));
                fileList.add(fileMap);
                billMap.put("fileList",fileList);

                //识别的发票子表
                List<EaBillItem> eaBillItemList = new ArrayList<EaBillItem>();
                if(items != null){
                    for (int i = 0; i < items.size(); i++) {
                        JSONObject itemsObject = (JSONObject)items.get(i);

                        EaBillItem eaBillItem = new EaBillItem();
                        eaBillItem.setSpecification(itemsObject.getString("specification"));     //货物或应税劳务、服务名称
                        eaBillItem.setName(itemsObject.getString("name"));     //规格型号
                        eaBillItem.setUnit(itemsObject.getString("unit"));     //单位
                        String price2 = EmptyUtil.checkNull(itemsObject.getString("price"));
                        BigDecimal price = new BigDecimal(0);
                        try {
                            price = !price2.equals("") ? new BigDecimal(price2) : new BigDecimal(0);
                        }catch (Exception e){
                        }
                        eaBillItem.setPrice(price);     //单价

                        // update-begin-by wujinbiao 2022/2/25 9:52 for 发票识别添加数量
                        if(StringUtils.isNotBlank(itemsObject.getString("quantity"))){
                            eaBillItem.setQuantity(new BigDecimal(itemsObject.getString("quantity")));
                        }else{
                            eaBillItem.setQuantity(new BigDecimal("0"));
                        }
                        // update-end-by wujinbiao 2022/2/25 9:52 for 发票识别添加数量

                        String total2 = EmptyUtil.checkNull(itemsObject.getString("total"));
                        BigDecimal total = new BigDecimal(0);
                        try {
                            total = !total2.equals("") ? new BigDecimal(total2) : new BigDecimal(0);
                        }catch (Exception e){
                        }
                        eaBillItem.setTotal(total);     //金额
                        String tax2 = EmptyUtil.checkNull(itemsObject.getString("tax"));
                        BigDecimal tax = new BigDecimal(0);
                        try {
                            tax = !tax2.equals("") ? new BigDecimal(tax2) : new BigDecimal(0);
                        }catch (Exception e){
                        }
                        eaBillItem.setTax(tax);     //税额

                        String taxRate = EmptyUtil.checkNull(itemsObject.getString("tax_rate"));
                        taxRate = taxRate.replace("%","");

                        eaBillItem.setTotalAmount(total.add(tax));      //总金额

                        BigDecimal taxRate2 = new BigDecimal(0);
                        try {
                            taxRate2 = !taxRate.equals("") ? new BigDecimal(taxRate) : new BigDecimal(0);
                        }catch (Exception e){
                        }
                        eaBillItem.setTaxRate(taxRate2);     //税率
                        eaBillItem.setLicensePlate(itemsObject.getString("license_plate"));     //车牌号(收费公路通行费增值税电子普通发票)
                        eaBillItem.setVehicleType(itemsObject.getString("vehicle_type"));     //类型(收费公路通行费增值税电子普通发票)
                        eaBillItem.setStartDate(itemsObject.getString("start_date"));     //通行日期起(收费公路通行费增值税电子普通发票)
                        eaBillItem.setEndDate(itemsObject.getString("end_date"));     //通行日期止(收费公路通行费增值税电子普通发票)
                        eaBillItem.setFromAirport(itemsObject.getString("from"));     //出发站(飞机票)
                        eaBillItem.setToAirport(itemsObject.getString("to"));     //到达站(飞机票)
                        eaBillItem.setDate(itemsObject.getString("date"));     //乘机日期
                        eaBillItem.setTime(itemsObject.getString("time"));     //乘机时间
                        eaBillItem.setFlightNumber(itemsObject.getString("flight_number"));     //航班号

                        String classNameName = EmptyUtil.checkNull(itemsObject.getString("class_name"));    //舱位等级(飞机票)
                        if(classNameName.contains("商务")){   //如商务经济舱
                            classNameName = "商务舱";
                        }
                        String internationalFlag = EmptyUtil.checkNull(itemsObject.getString("international_flag"));    //国内国际标签:国内(D)(飞机票)
                        String className = changeIdToNameUtil.getIdByPlaneName(classNameName,internationalFlag);
                        eaBillItem.setClassName(className);
                        eaBillItem.setSeat(itemsObject.getString("seat"));    //座位等级

                        List<Map<String,Object>> mapList2 = eaBillItemMapper.getAirPlaneSeatName(className);
                        if(mapList2.size() > 0){
                            Map<String,Object> map2 = mapList2.get(0);
                            eaBillItem.setClassNameName(EmptyUtil.checkNull(map2.get("classNameName")));
                        }

                        eaBillItem.setCarrier(itemsObject.getString("carrier"));     //承运人(飞机票)
                        eaBillItem.setAllow(itemsObject.getString("allow"));     //免费行李(飞机票)
                        eaBillItem.setCarType(itemsObject.getString("car_type"));     //车型(滴滴)
                        eaBillItem.setTimeGeton(itemsObject.getString("time_geton"));     //上车时间(滴滴)
                        eaBillItem.setCity(itemsObject.getString("city"));     //市
                        eaBillItem.setStationGeton(itemsObject.getString("station_geton"));     //起点(滴滴)
                        eaBillItem.setStationGetoff(itemsObject.getString("station_getoff"));     //终点(滴滴)
                        eaBillItem.setMileage(itemsObject.getString("mileage"));     //里程（公里）(滴滴)

                        eaBillItemList.add(eaBillItem);
                    }
                }

                //将发票子表信息保存到items节点
                billMap.put("eaBillItemList",eaBillItemList);
                returnMap.put("validation","");

                // 判断发票代码是否为空
                if(StringUtils.isNotBlank(data.getString("code"))){
                    String code = data.getString("code");
                    String number = data.getString("number");
                    String check_code = data.getString("check_code");
                    if(check_code != null && check_code.length() > 6){
                        check_code = check_code.substring(check_code.length() - 6,check_code.length());
                    }
                    String electronic_mark = data.getString("electronic_mark") != null ? data.getString("electronic_mark") : "0";
                    String pretax_amount = data.getString("pretax_amount");

                    Map map = new HashMap();
                    map.put("code",code);
                    map.put("number",number);
                    map.put("date",date);
                    map.put("type",type);
                    map.put("check_code",check_code);
                    map.put("electronic_mark",electronic_mark);
                    map.put("pretax_amount",pretax_amount);

                    //发票验真
                    String result2 = GlorityService.getFapiaoValidation(map);
                    JSONObject jsonObject2 = JSON.parseObject(result2);
                    Object responseStr = jsonObject2.getString("response");

                    if(responseStr == null){
                        returnMap.put("validation",false);
                    }else{
                        JSONObject rsdata2 = jsonObject2.parseObject(jsonObject2.getString("response")).getJSONObject("data");
                        JSONArray identifyResults2 = rsdata2.getJSONArray("identify_results");
                        if(identifyResults2 != null && identifyResults2.size() > 0){
                            JSONObject rs2 = identifyResults2.getJSONObject(idx);
                            JSONObject data2 = rs2.getJSONObject("validation");
                            String code2 = data2.getString("code");
                            if(code2.equals("10000")){   //验真通过
                                returnMap.put("validation",true);
                            }else{
                                returnMap.put("validation",false);
                                return Result.error("发票验真不通过!");
                            }
                        }else{
                            returnMap.put("validation",false);
                            return Result.error("发票验真不通过!");
                        }
                    }
                }

            }
            returnMap.put("fileName",  file.getOriginalFilename());
            returnMap.put("data",billMap);
            return Result.OK(returnMap);
        }
        catch (Exception e) {
//        catch (IOException e) {
            e.printStackTrace();
//            result.setMessage("调用发票识别接口出错！");
            result.setMessage(e.getMessage());
            result.setSuccess(false);
            return result;
        }
    }

    /**
     * 本地文件上传
     *
     * @param mf      文件
     * @param bizPath 自定义路径
     * @return
     */
    private String uploadLocal(MultipartFile mf, String bizPath) {
        try {
            String ctxPath = uploadpath;
            String fileName = null;
            File file = new File(ctxPath + File.separator + bizPath + File.separator);
            if (!file.exists()) {
                file.mkdirs();// 创建文件根目录
            }
            String orgName = mf.getOriginalFilename();// 获取文件名
            orgName = CommonUtils.getFileName(orgName);
            if (orgName.indexOf(".") != -1) {
                fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.indexOf("."));
            } else {
                fileName = orgName + "_" + System.currentTimeMillis();
            }
            String savePath = file.getPath() + File.separator + fileName;
            File savefile = new File(savePath);
//            FileCopyUtils.copy(mf.getBytes(), savefile);
            FileUtils.copyInputStreamToFile(mf.getInputStream(),savefile);
            String dbpath = null;
            if (oConvertUtils.isNotEmpty(bizPath)) {
                dbpath = bizPath + File.separator + fileName;
            } else {
                dbpath = fileName;
            }
            if (dbpath.contains("\\")) {
                dbpath = dbpath.replace("\\", "/");
            }
            return dbpath;
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        return "";
    }

    /**
     * app查询出差目的
     *
     * @return
     */
    @AutoLog(value = "app查询出差目的")
    @ApiOperation(value="app查询出差目的", notes="app查询出差目的")
    @RequestMapping(value = "/sysDict/getTravelPurpose", method = RequestMethod.POST)
    public Result<List<DictModel>> getTravelPurpose() {
        Result<List<DictModel>> result = new Result<>();
        try {
            List<DictModel> list = sysDictService.queryDictItemsByCode("travelPurpose");  //code
            result.setResult(list);
            result.setSuccess(true);
        } catch (Exception e) {
            log.error(e.getMessage(),e);
        }
        return result;
    }

    /**
     * app查询出差地点类型
     *
     * @return
     */
    @AutoLog(value = "app查询出差地点类型")
    @ApiOperation(value="app查询出差地点类型", notes="app查询出差地点类型")
    @RequestMapping(value = "/sysDict/getTravelRegionType", method = RequestMethod.POST)
    public Result<List<DictModel>> getTravelRegionType() {
        Result<List<DictModel>> result = new Result<>();
        try {
            List<DictModel> list = sysDictService.queryDictItemsByCode("regionType");  //code
            result.setResult(list);
            result.setSuccess(true);
        } catch (Exception e) {
            log.error(e.getMessage(),e);
        }
        return result;
    }

    /**
     * app查询出差期间类型
     *
     * @return
     */
    @AutoLog(value = "app查询出差期间类型")
    @ApiOperation(value="app查询出差期间类型", notes="app查询出差期间类型")
    @RequestMapping(value = "/sysDict/getTravelType", method = RequestMethod.POST)
    public Result<List<DictModel>> getTravelType() {
        Result<List<DictModel>> result = new Result<>();
        try {
            List<DictModel> list = sysDictService.queryDictItemsByCode("travelType");  //code
            result.setResult(list);
            result.setSuccess(true);
        } catch (Exception e) {
            log.error(e.getMessage(),e);
        }
        return result;
    }

    /**
     * app查询交易对象类型
     *
     * @return
     */
    @AutoLog(value = "app查询交易对象类型")
    @ApiOperation(value="app查询交易对象类型", notes="app查询交易对象类型")
    @RequestMapping(value = "/sysDict/getTradeType", method = RequestMethod.POST)
    public Result<List<DictModel>> getTradeType() {
        Result<List<DictModel>> result = new Result<>();
        try {
            List<DictModel> list = sysDictService.queryDictItemsByCode("ea_trade_type");  //code
            result.setResult(list);
            result.setSuccess(true);
        } catch (Exception e) {
            log.error(e.getMessage(),e);
        }
        return result;
    }

    /**
     * app查询补贴标准
     *
     * @return
     */
    @AutoLog(value = "app查询补贴标准")
    @ApiOperation(value="app查询补贴标准", notes="app查询补贴标准")
    @RequestMapping(value = "/sysDict/getAllowanceCost", method = RequestMethod.POST)
    public Result<?> get() {
        AllowanceCostVo allowanceCostVo = new AllowanceCostVo();
        try {
            List<DictModel> list = sysDictService.queryDictItemsByCode("food_allowance_cost");  //伙食补助费标准
            List<DictModel> list2 = sysDictService.queryDictItemsByCode("city_traffic_cost");  //市内交通费标准
            if(list.size() > 0){
                allowanceCostVo.setFood_allowance_cost(list.get(0).getValue());
            }
            if(list2.size() > 0){
                for (int i = 0; i < list2.size(); i++) {
                    DictModel dictModel = list2.get(i);
                    String text = dictModel.getText();
                    if(text.equals("非五区")){
                        allowanceCostVo.setCity_traffic_cost_fwq(dictModel.getValue());
                    }else{
                        allowanceCostVo.setCity_traffic_cost(dictModel.getValue());
                    }
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage(),e);
        }
        return Result.OK(allowanceCostVo);
    }

    /**
     * app查询配车类型
     *
     * @return
     */
    @AutoLog(value = "app查询配车类型")
    @ApiOperation(value="app查询配车类型", notes="app查询配车类型")
    @RequestMapping(value = "/sysDict/getDeployCarType", method = RequestMethod.POST)
    public Result<List<DictModel>> getDeployCarType() {
        Result<List<DictModel>> result = new Result<>();
        try {
            List<DictModel> list = sysDictService.queryDictItemsByCode("deploy_car_type");  //code
            result.setResult(list);
            result.setSuccess(true);
        } catch (Exception e) {
            log.error(e.getMessage(),e);
        }
        return result;
    }

    /**
     * app查询版本更新
     *
     * @return
     */
    @AutoLog(value = "app查询版本更新")
    @ApiOperation(value="app查询版本更新", notes="app查询版本更新")
    @RequestMapping(value = "/getAppVersionUpdate", method = RequestMethod.POST)
    public Map<String,Object> getAppVersionUpdate() {
        SysDictItem sysDictItem = sysDictItemMapper.selectById("1453896667855659009");   //获取版本号
        SysDictItem sysDictItem2 = sysDictItemMapper.selectById("1453896484493271042");   //更新内容
        SysDictItem sysDictItem3 = sysDictItemMapper.selectById("1453896427241021441");   //下载地址
        String version = sysDictItem.getDescription();
        String note = sysDictItem2.getDescription();
        String url = sysDictItem3.getDescription();

        Map<String,Object> returnMap = new HashMap<String,Object>();
        returnMap.put("version",version);
        returnMap.put("note",note);
        returnMap.put("url",url);
        return returnMap;
    }

    /**
     * app查询单据类型
     *
     * @return
     */
    @AutoLog(value = "app查询单据类型")
    @ApiOperation(value="app查询单据类型", notes="app查询单据类型")
    @RequestMapping(value = "/sysDict/queryFormTypeList", method = RequestMethod.POST)
    public Result<List<DictModel>> queryFormTypeList() {
        Result<List<DictModel>> result = new Result<>();
        try {
            List<DictModel> list = sysDictService.queryDictItemsByCode("form_type");  //code
            result.setResult(list);
            result.setSuccess(true);
        } catch (Exception e) {
            log.error(e.getMessage(),e);
        }
        return result;
    }

    /**
     * app查询关联设置类型
     *
     * @return
     */
    @AutoLog(value = "app查询关联设置类型")
    @ApiOperation(value="app查询关联设置类型", notes="app查询关联设置类型")
    @RequestMapping(value = "/sysDict/queryRelatedTtype", method = RequestMethod.POST)
    public Result<List<DictModel>> queryRelatedTtype() {
        Result<List<DictModel>> result = new Result<>();
        try {
            List<DictModel> list = sysDictService.queryDictItemsByCode("glszlx");  //code
            result.setResult(list);
            result.setSuccess(true);
        } catch (Exception e) {
            log.error(e.getMessage(),e);
        }
        return result;
    }

}
